// 组件渲染顺序
// 1. 首先执行 getInitialState 方法
// 2. 再执行 render 方法
// 3. 最后执行 componentDidMount 方法, 并且如果有 child 时, 要等 child(存在的) 的 componentDidMount 执行完成后才执行
//
// props 在组件内是不可变的, 属于父组件
// state 是可变的, 属于组件私有的. 调用 this.setState(/* state */) 来改变它, 当state更新后组件会重新渲染自己

let comments = [];
var Comment = React.createClass({
    reMarkUp() {
        var md = new Remarkable();
        var __html = md.render(this.props.children.toString());
        return {__html};
    },
    getInitialState() {
        console.log('Comment getInitialState');
        return null;
    },
    componentDidMount(){
        console.log('Comment componentDidMount');
    },
    render() {
        console.log('Comment render');
        return (
            <div className="comment">
                <h2 className="commentAuthor">
                    {this.props.author}
                </h2>
                <span dangerouslySetInnerHTML={this.reMarkUp()}/>
            </div>
        );
    }
});

var CommentList = React.createClass({
    getInitialState() {
        console.log('CommentList getInitialState');
        return null;
    },
    componentDidMount(){
        console.log('CommentList componentDidMount');
    },
    render() {
        console.log('CommentList render');
        let commentNodes = this.props.data.map(comment => (
            <Comment author={comment.author} key={comment.id}>
                {comment.text}
            </Comment>
        ));
        return (
            <div className="comment-list">
                {commentNodes}
            </div>
        );
    }
});

var CommentForm = React.createClass({
    handleSubmit(e) {
        e.preventDefault();
        var author = this.state.author.trim();
        var text = this.state.text.trim();
        if (!text || !author) {
            return;
        }
        var id = new Date().getTime();
        this.props.onCommentSubmit({id, author, text});
        this.setState({author: '', text: ''});
    },
    handleAuthorChange(e) {
        this.setState({
            author: e.target.value
        });
    },
    handleTextChange(e) {
        this.setState({
            text: e.target.value
        });
    },
    getInitialState() {
        console.log('CommentForm getInitialState');
        return {author: '', text: ''};
    },
    componentDidMount() {
        console.log('CommentForm componentDidMount');
    },
    render() {
        console.log('CommentForm render');
        return (
            <form className="commentForm" onSubmit={this.handleSubmit}>
                <input type="text" placeholder="Your name" value={this.state.author} onChange={this.handleAuthorChange}/>
                <input type="text" placeholder="Say something..." value={this.state.text} onChange={this.handleTextChange}/>
                <input type="submit" value="Post"/>
            </form>
        );
    }
});

var CommentBox = React.createClass({
    getInitialState() {
        console.log('CommentBox getInitialState');
        return {data: []};
    },
    componentDidMount() {
        console.log('CommentBox componentDidMount');
        this.loadComments();
    },
    loadComments() {
        var me = this;
        comments = new Proxy([{
            "id"    : 1388534400000,
            "author": "Pete Hunt",
            "text"  : "Hey there!"
        }, {
            "id"    : 1420070400000,
            "author": "Paul O’Shannessy",
            "text"  : "React is *great*!"
        }], {
            set(target, name, value) {
                console.log(name, value);
                target[name] = value;
                me.setState({
                    data: target
                });
                return true;
            }
        });
        this.setState({
            data: comments
        });
    },
    handleCommentSubmit(comment) {
        comments.push(comment);
    },
    render() {
        console.log('CommentBox render');
        return (
            <div className="commentBox">
                <h1>Comments</h1>
                <CommentList data={this.state.data}/>
                <CommentForm onCommentSubmit={this.handleCommentSubmit}/>
            </div>
        );
    }
});

ReactDOM.render(
    <CommentBox url="comments.json"/>,
    document.querySelector('#container')
);